home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / Kubuntu 8.10 / kubuntu-8.10-desktop-i386.iso / casper / filesystem.squashfs / etc / init.d / checkroot.sh < prev    next >
Linux/UNIX/POSIX Shell Script  |  2008-10-14  |  11KB  |  415 lines

  1. #! /bin/sh
  2. ### BEGIN INIT INFO
  3. # Provides:          checkroot
  4. # Required-Start:    mountdevsubfs hostname
  5. # Required-Stop:     
  6. # Should-Start:      keymap hwclockfirst hdparm bootlogd
  7. # Should-stop:
  8. # Default-Start:     S
  9. # Default-Stop:
  10. # Short-Description: Check to root file system.
  11. ### END INIT INFO
  12.  
  13. # Include /usr/bin in path to find on_ac_power if /usr/ is on the root
  14. # partition.
  15. PATH=/lib/init:/sbin:/bin:/usr/bin
  16. FSCK_LOGFILE=/var/log/fsck/checkroot
  17. [ "$FSCKFIX" ] || FSCKFIX=no
  18. [ "$SULOGIN" ] || SULOGIN=no
  19. . /lib/init/vars.sh
  20.  
  21. . /lib/lsb/init-functions
  22. . /lib/init/mount-functions.sh
  23. . /lib/init/splash-functions-base
  24. . /lib/init/usplash-fsck-functions.sh
  25.  
  26. do_start () {
  27.     #
  28.     # Set SULOGIN in /etc/default/rcS to yes if you want a sulogin to
  29.     # be spawned from this script *before anything else* with a timeout,
  30.     # like sysv does.
  31.     #
  32.     [ "$SULOGIN" = yes ] && sulogin -t 30 $CONSOLE
  33.  
  34.     KERNEL="$(uname -s)"
  35.     MACHINE="$(uname -m)"
  36.  
  37.     #
  38.     # Read /etc/fstab, looking for:
  39.     # 1) The root filesystem, resolving LABEL=*|UUID=* entries to the
  40.     #     device node,
  41.     # 2) Swap that is on a md device or a file that may be on a md 
  42.     #     device,
  43.     # 3) The mount parameters for a devfs filesystem.
  44.     #
  45.  
  46.     exec 9<&0 </etc/fstab
  47.  
  48.     fstabroot=/dev/root
  49.     rootdev=none
  50.     roottype=none
  51.     rootopts=defaults
  52.     rootmode=rw
  53.     rootcheck=no
  54.     swap_on_lv=no
  55.     swap_on_file=no
  56.     devfs=
  57.  
  58.     while read DEV MTPT FSTYPE OPTS DUMP PASS JUNK
  59.     do
  60.         case "$DEV" in
  61.           ""|\#*)
  62.             continue;
  63.             ;;
  64.           /dev/mapper/*)
  65.             [ "$FSTYPE" = "swap" ] && swap_on_lv=yes
  66.             ;;
  67.           /dev/*)
  68.             ;;
  69.           LABEL=*|UUID=*)
  70.             if [ "$MTPT" = "/" ] && which findfs >/dev/null 2>&1
  71.             then
  72.                 DEV="$(findfs "$DEV")"
  73.             fi
  74.             ;;
  75.           /*)
  76.             [ "$FSTYPE" = "swap" ] && swap_on_file=yes
  77.             ;;
  78.           *)
  79.             # Devfs definition ?
  80.             if [ "$FSTYPE" = "devfs" ] && [ "$MTPT" = "/dev" ] && mountpoint -q /dev
  81.             then
  82.                 devfs="-t $FSTYPE $DEV $MTPT"
  83.             fi
  84.             ;;
  85.         esac
  86.         [ "$MTPT" != "/" ] && continue
  87.         rootdev="$DEV"
  88.         fstabroot="$DEV"
  89.         rootopts="$OPTS"
  90.         roottype="$FSTYPE"
  91.         ( [ "$PASS" != 0 ] && [ "$PASS" != "" ]   ) && rootcheck=yes
  92.         ( [ "$FSTYPE" = "nfs" ] || [ "$FSTYPE" = "nfs4" ] ) && rootcheck=no
  93.         case "$OPTS" in
  94.           ro|ro,*|*,ro|*,ro,*)
  95.             rootmode=ro
  96.             ;;
  97.         esac
  98.     done
  99.  
  100.     exec 0<&9 9<&-
  101.  
  102.     #
  103.     # Activate the swap device(s) in /etc/fstab. This needs to be done
  104.     # before fsck, since fsck can be quite memory-hungry.
  105.     #
  106.     ENABLE_SWAP=no
  107.     case "$KERNEL" in
  108.       Linux)
  109.           if [ "$NOSWAP" = yes ]
  110.         then
  111.             [ "$VERBOSE" = no ] || log_warning_msg "Not activating swap as requested via bootoption noswap."
  112.             ENABLE_SWAP=no
  113.         else
  114.             if [ "$swap_on_lv" = yes ]
  115.             then
  116.                 [ "$VERBOSE" = no ] || log_warning_msg "Not activating swap on logical volume."
  117.             elif [ "$swap_on_file" = yes ]
  118.             then
  119.                 [ "$VERBOSE" = no ] || log_warning_msg "Not activating swap on swapfile."
  120.             else
  121.                 ENABLE_SWAP=yes
  122.             fi
  123.         fi
  124.         ;;
  125.       *)
  126.         ENABLE_SWAP=yes
  127.         ;;
  128.     esac
  129.     if [ "$ENABLE_SWAP" = yes ]
  130.     then
  131.         if [ "$VERBOSE" = no ]
  132.         then
  133.             log_action_begin_msg "Activating swap"
  134.             swapon -a -e >/dev/null 2>&1
  135.             log_action_end_msg $?
  136.         else
  137.             log_daemon_msg "Activating swap"
  138.             swapon -a -v
  139.             log_end_msg $?
  140.         fi
  141.     fi
  142.  
  143.     #
  144.     # Does the root device in /etc/fstab match with the actual device ?
  145.     # If not we try to use the /dev/root alias device, and if that
  146.     # fails we create a temporary node in /lib/init/rw.
  147.     #
  148.     if [ "$rootcheck" = yes ]
  149.     then
  150.         ddev="$(mountpoint -qx $rootdev)"
  151.         rdev="$(mountpoint -d /)"
  152.         if [ "$ddev" != "$rdev" ] && [ "$ddev" != "4:0" ]
  153.         then
  154.             if [ "$(mountpoint -qx /dev/root)" = "4:0" ]
  155.             then
  156.                 rootdev=/dev/root
  157.             else
  158.                 if \
  159.                     rm -f /lib/init/rw/rootdev \
  160.                     && mknod -m 600 /lib/init/rw/rootdev b ${rdev%:*} ${rdev#*:} \
  161.                     && [ -e /lib/init/rw/rootdev ]
  162.                 then
  163.                     rootdev=/lib/init/rw/rootdev
  164.                 else
  165.                     rootfatal=yes
  166.                 fi
  167.             fi
  168.         fi
  169.     fi
  170.  
  171.     #
  172.     # Bother, said Pooh.
  173.     #
  174.     if [ "$rootfatal" = yes ]
  175.     then
  176.         log_failure_msg "The device node $rootdev for the root filesystem is missing or incorrect 
  177. or there is no entry for the root filesystem listed in /etc/fstab. 
  178. The system is also unable to create a temporary node in /lib/init/rw. 
  179. This means you have to fix the problem manually."
  180.         log_warning_msg "A maintenance shell will now be started. 
  181. CONTROL-D will terminate this shell and restart the system."
  182.         # Start a single user shell on the console
  183.         if ! sulogin $CONSOLE
  184.         then
  185.             log_failure_msg "Attempt to start maintenance shell failed. 
  186. Will restart in 5 seconds."
  187.             sleep 5
  188.         fi
  189.         [ "$VERBOSE" = no ] || log_action_msg "Will now restart"
  190.         reboot -f
  191.     fi
  192.  
  193.     # See if we're on AC Power.  If not, we're not gonna run our
  194.     # check.  If on_ac_power (in /usr/) is unavailable, behave as
  195.     # before and check all file systems needing it.
  196.     if which on_ac_power >/dev/null 2>&1 && [ "$rootcheck" = yes ]
  197.     then
  198.         if [ -d /proc/acpi ]; then
  199.             modprobe ac >/dev/null 2>&1
  200.         fi
  201.         on_ac_power >/dev/null 2>&1
  202.         if [ "$?" -eq 1 ]
  203.         then
  204.             log_warning_msg "On battery power, so skipping file system check."
  205.             rootcheck=no
  206.         fi
  207.     fi
  208.  
  209.     #
  210.     # See if we want to check the root file system.
  211.     #
  212.     FSCKCODE=0
  213.     if [ -f /fastboot ]
  214.     then
  215.         [ "$rootcheck" = yes ] && log_warning_msg "Fast boot enabled, so skipping file system check."
  216.         rootcheck=no
  217.     fi
  218.  
  219.     if [ "$rootcheck" = yes ]
  220.     then
  221.         #
  222.         # Ensure that root is quiescent and read-only before fsck'ing.
  223.         #
  224.         # mount -n -o remount,ro / would be the correct syntax but
  225.         # mount can get confused when there is a "bind" mount defined
  226.         # in fstab that bind-mounts "/" somewhere else.
  227.         #
  228.         # So we use mount -n -o remount,ro $rootdev / but that can
  229.         # fail on older kernels on sparc64/alpha architectures due
  230.         # to a bug in sys_mount().
  231.         #
  232.         # As a compromise we try both.
  233.         #
  234.         if \
  235.             ! mount    -n -o remount,ro              $rootdev /              \
  236.             && ! mount -n -o remount,ro -t dummytype $rootdev /  2>/dev/null \
  237.             && ! mount -n -o remount,ro                       /  2>/dev/null
  238.         then
  239.             log_failure_msg "Cannot check root file system because it is not mounted read-only."
  240.             rootcheck=no
  241.         fi
  242.     fi
  243.  
  244.     #
  245.     # The actual checking is done here.
  246.     #
  247.     if [ "$rootcheck" = yes ]
  248.     then
  249.         if [ -f /forcefsck ]
  250.         then
  251.             force="-f"
  252.         else
  253.             force=""
  254.         fi
  255.  
  256.         if [ "$FSCKFIX" = yes ]
  257.         then
  258.             fix="-y"
  259.         else
  260.             fix="-a"
  261.         fi
  262.  
  263.         spinner="-C"
  264.         case "$TERM" in
  265.           dumb|network|unknown|"")
  266.             spinner="" ;;
  267.         esac
  268.         # This Linux/s390 special case should go away.
  269.         if [ "${KERNEL}:${MACHINE}" = Linux:s390 ]
  270.         then
  271.             spinner=""
  272.         fi
  273.         
  274.         if [ "$VERBOSE" = no ]
  275.         then
  276.             log_action_begin_msg "Checking root file system"
  277.                         if [ "$roottype" = "ext2" -o "$roottype" = "ext3" ] && pidof usplash; then
  278.                             PROGRESS_FILE=`mktemp -p /var/run` || PROGRESS_FILE=/var/run/checkroot_fsck
  279.                             set -m
  280.                             logsave -s $FSCK_LOGFILE fsck -C3 $force $fix -t $roottype $rootdev >/dev/console 2>&1 3>$PROGRESS_FILE &
  281.                             set +m
  282.                             usplash_progress "$PROGRESS_FILE"
  283.                             rm -f $PROGRESS_FILE
  284.                         else
  285.                             logsave -s $FSCK_LOGFILE fsck $spinner $force $fix -t $roottype $rootdev
  286.                             FSCKCODE=$?
  287.                         fi
  288.             if [ "$FSCKCODE" = 0 ]
  289.             then
  290.                 log_action_end_msg 0
  291.             else
  292.                 log_action_end_msg 1 "code $FSCKCODE"
  293.             fi
  294.         else
  295.             log_daemon_msg "Will now check root file system"
  296.             logsave -s $FSCK_LOGFILE fsck $spinner $force $fix -V -t $roottype $rootdev
  297.             FSCKCODE=$?
  298.             log_end_msg $FSCKCODE
  299.         fi
  300.     fi
  301.  
  302.     #
  303.     # If there was a failure, drop into single-user mode.
  304.     #
  305.     # NOTE: "failure" is defined as exiting with a return code of
  306.     # 4 or larger. A return code of 1 indicates that file system
  307.     # errors were corrected but that the boot may proceed. A return
  308.     # code of 2 or 3 indicates that the system should immediately reboot.
  309.     #
  310.     if [ "$FSCKCODE" -gt 3 ]
  311.     then
  312.         # Surprise! Re-directing from a HERE document (as in "cat << EOF")
  313.         # does not work because the root is currently read-only.
  314.         log_failure_msg "An automatic file system check (fsck) of the root filesystem failed. 
  315. A manual fsck must be performed, then the system restarted. 
  316. The fsck should be performed in maintenance mode with the 
  317. root filesystem mounted in read-only mode."
  318.         log_warning_msg "The root filesystem is currently mounted in read-only mode. 
  319. A maintenance shell will now be started. 
  320. After performing system maintenance, press CONTROL-D 
  321. to terminate the maintenance shell and restart the system."
  322.         # Start a single user shell on the console
  323.         if ! sulogin $CONSOLE
  324.         then
  325.             log_failure_msg "Attempt to start maintenance shell failed. 
  326. Will restart in 5 seconds."
  327.             sleep 5
  328.         fi
  329.         [ "$VERBOSE" = no ] || log_action_msg "Will now restart"
  330.         reboot -f
  331.     elif [ "$FSCKCODE" -gt 1 ]
  332.     then
  333.         log_failure_msg "The file system check corrected errors on the root partition 
  334. but requested that the system be restarted."
  335.         log_warning_msg "The system will be restarted in 5 seconds."
  336.         sleep 5
  337.         [ "$VERBOSE" = no ] || log_action_msg "Will now restart"
  338.         reboot -f
  339.     fi
  340.  
  341.     #
  342.     # Remount root to final mode (rw or ro).
  343.     #
  344.     # See the comments above at the previous "mount -o remount"
  345.     # for an explanation why we try this twice.
  346.     #
  347.     if ! mount -n -o remount,$rootopts,$rootmode $fstabroot / 2>/dev/null
  348.     then
  349.         mount -n -o remount,$rootopts,$rootmode /
  350.     fi
  351.  
  352.     #
  353.     # We only create/modify /etc/mtab if the location where it is
  354.     # stored is writable. If /etc/mtab is a symlink into /proc/
  355.     # then it is not writable.
  356.     #
  357.     INIT_MTAB_FILE=no
  358.     MTAB_PATH="$(readlink -f /etc/mtab || :)"
  359.     case "$MTAB_PATH" in
  360.       /proc/*)
  361.         ;;
  362.       /*)
  363.         if touch "$MTAB_PATH" >/dev/null 2>&1
  364.         then
  365.             :> "$MTAB_PATH"
  366.             rm -f ${MTAB_PATH}~
  367.             INIT_MTAB_FILE=yes
  368.         fi
  369.         ;;
  370.       "")
  371.         [ -L /etc/mtab ] && MTAB_PATH="$(readlink /etc/mtab)"
  372.         if [ "$MTAB_PATH" ]
  373.         then
  374.             log_failure_msg "Cannot initialize ${MTAB_PATH}."
  375.         else
  376.             log_failure_msg "Cannot initialize /etc/mtab."
  377.         fi
  378.         ;;
  379.       *)
  380.         log_failure_msg "Illegal mtab location '${MTAB_PATH}'."
  381.         ;;
  382.     esac
  383.  
  384.     if [ "$INIT_MTAB_FILE" = yes ]
  385.     then
  386.         [ "$roottype" != none ] &&
  387.             mount -f -o $rootopts -t $roottype $fstabroot /
  388.         [ "$devfs" ] && mount -f $devfs
  389.     fi
  390.  
  391.     #
  392.     # Remove /lib/init/rw/rootdev if we created it.
  393.     #
  394.     rm -f /lib/init/rw/rootdev
  395. }
  396.  
  397. case "$1" in
  398.   start|"")
  399.     do_start
  400.     ;;
  401.   restart|reload|force-reload)
  402.     echo "Error: argument '$1' not supported" >&2
  403.     exit 3
  404.     ;;
  405.   stop)
  406.     # No-op
  407.     ;;
  408.   *)
  409.     echo "Usage: checkroot.sh [start|stop]" >&2
  410.     exit 3
  411.     ;;
  412. esac
  413.  
  414. :
  415.